/*
 * Copyright (c) 2010 Curtis Boyden.  All rights reserved. 
 * This software was developed by Curtis Boyden and is provided under the terms 
 * of the GNU Lesser General Public License, Version 2.1. You may not use 
 * this file except in compliance with the license. If you need a copy of the license, 
 * please go to http://www.gnu.org/licenses/lgpl-2.1.txt. The Original Code is ejMud
 * (Ewerp Java MUD).  The Initial Developer is Curtis Boyden.
 *
 * Software distributed under the GNU Lesser Public License is distributed on an "AS IS" 
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or  implied. Please refer to 
 * the license for the specific language governing your rights and limitations.
 */
package com.ewerp.mud.commands.engine;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.ewerp.mud.commands.ICommand;
import com.ewerp.mud.commands.ICommandEngine;
import com.ewerp.mud.commands.MockCommand;
import com.ewerp.mud.core.exceptions.FailedToPushCommandException;
import com.ewerp.mud.core.lifecycle.ILifecycleListener;
import com.ewerp.mud.core.plugin.IPlugin;

public class TestEwerpCommandEngine {
    private ICommandEngine commandEngine = null;
    
    @Before
    public void setup() {
        commandEngine = new EwerpCommandEngine();
    }
    
    @After
    public void breakDown() {
        
    }
    
    @Test
    public void testPluginType() {
        assertTrue(((IPlugin)commandEngine).getInterfaces().contains(ICommandEngine.class));
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void testNullCommand() throws IllegalArgumentException, FailedToPushCommandException {
        commandEngine.pushCommand(null);
    }
    
    @Test
    public void testValidCommand() throws IllegalArgumentException, FailedToPushCommandException {
        commandEngine.pushCommand(new MockCommand());
    }
    
    @Test
    public void testCommandExecution() throws IllegalArgumentException, FailedToPushCommandException {
        ICommand commandOnce = new MockCommand();
        ICommand commandTwice = new MockCommand();

        ((ILifecycleListener)commandEngine).start();
        
        // Insert a few more mock commands before the one to verify
        commandEngine.pushCommand(new MockCommand());
        commandEngine.pushCommand(new MockCommand());
        commandEngine.pushCommand(new MockCommand());
        
        commandEngine.pushCommand(commandOnce);
        
        commandEngine.pushCommand(commandTwice);
        commandEngine.pushCommand(commandTwice);
        
        // Wait 1 second to give the engine time to process the command object
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // Do not care about this
        }
        
        assertEquals(1, ((MockCommand)commandOnce).getMethodInvocationCount("execute"));
        assertEquals(2, ((MockCommand)commandTwice).getMethodInvocationCount("execute"));
    }
}
